package redecolaborativa.server.testes;



import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import redecolaborativa.server.objetos.Item;
import redecolaborativa.server.sistema.Gerenciador;
import redecolaborativa.server.sistema.Sessao;
import redecolaborativa.server.sistema.Usuario;

public class TesteGerenciador {
	private Gerenciador gerenciador;
	
	@Before
	public void iniciaTeste() {
		gerenciador = Gerenciador.getInstance();		
	}

	@Test
	public void testAbrirSessao() throws Exception {
		gerenciador.cadastrarUsuario("Lilia", "liliars", "endereco");
		try {
			gerenciador.abrirSessao("");
		} catch (Exception ex) {
			assertEquals("Login inválido", ex.getMessage());
		} try {
			gerenciador.abrirSessao("login");
		} catch (Exception ex) {
			assertEquals("Usuário inexistente", ex.getMessage());
		}
		Sessao sessao = gerenciador.abrirSessao(gerenciador.usuarios().get(0).getLogin());
		assertTrue(gerenciador.sessoesAbertas().contains(sessao));
	}

	@Test
	public void testCadastrarUsuario() throws Exception {
		gerenciador.reset();
		gerenciador.cadastrarUsuario("nome", "login", "endereco");
		try {
			gerenciador.cadastrarUsuario("nome", "login", "endereco");
		} catch (Exception ex) {
			assertEquals("Já existe um usuário com este login", ex.getMessage());
		}
		gerenciador.cadastrarUsuario("Mariana", "mariimello", "Ipanema");
		assertTrue(gerenciador.usuarios().size() == 2);
		gerenciador.cadastrarUsuario("Marcella", "marcelinhasilva", "Jose do Patrocinio");
		assertTrue(gerenciador.usuarios().size() == 3);
		gerenciador.cadastrarUsuario("Ramon", "smithpb", "Jose do Patrocinio");
		assertTrue(gerenciador.usuarios().size() == 4);
	}

	@Test
	public void testGetAtributoDeUmUsuario() throws Exception {
		cadastraUsuarios();
		try {
			gerenciador.getAtributoDeUmUsuario("", "nome");
		} catch (Exception ex) {
			assertEquals("Login inválido", ex.getMessage());
		} try {
			gerenciador.getAtributoDeUmUsuario("login", null);
		} catch (Exception ex) {
			assertEquals("Atributo inválido", ex.getMessage());
		} try {
			gerenciador.getAtributoDeUmUsuario("lilia", "nome");
		} catch (Exception ex) {
			assertEquals("Usuário inexistente", ex.getMessage());
		} try {
			gerenciador.getAtributoDeUmUsuario("login", "atributoInexist");
		} catch (Exception ex) {
			assertEquals("Atributo inexistente", ex.getMessage());
		}
		assertEquals("nome", gerenciador.getAtributoDeUmUsuario("login", "nome"));
		assertEquals("endereco3", gerenciador.getAtributoDeUmUsuario("login3", "endereco"));
		assertNotSame("nomeDois", gerenciador.getAtributoDeUmUsuario("login2", "endereco"));
	}

	@Test
	public void testLocalizaUsuario() throws Exception {
		gerenciador.reset();
		cadastraUsuarios();
		gerenciador.abrirSessao("login");
		try {
			gerenciador.localizaUsuario("1", "", "atributo");
		} catch (Exception ex) {
			assertEquals("Palavra-chave inválida", ex.getMessage());
		} try {
			gerenciador.localizaUsuario("1", "chave", null);
		} catch (Exception ex) {
			assertEquals("Atributo inválido", ex.getMessage());
		} try {
			gerenciador.localizaUsuario("1", "chave", "atributo");
		} catch (Exception ex) {
			assertEquals("Atributo inexistente", ex.getMessage());
		}
		gerenciador.cadastrarUsuario("Mariana", "mariimello", "Ipanema");
		gerenciador.cadastrarUsuario("Marcella", "marcelinhasilva", "Jose do Patrocinio");
		gerenciador.abrirSessao("mariimello"); gerenciador.abrirSessao("marcelinhasilva");
		assertEquals("Mariana - Ipanema", gerenciador.localizaUsuario("1", "mariana", "nome"));
		assertEquals("Mariana - Ipanema", gerenciador.localizaUsuario("1", "ipanema", "endereco"));
		assertEquals("Marcella - Jose do Patrocinio", gerenciador.localizaUsuario("2", "Marcella", "nome"));	
	}

	@Test
	public void testLocalizaUsuarioPorSessao() throws Exception {
		try {
			gerenciador.localizaUsuarioPorSessao(null);
		} catch (Exception ex) {
			assertEquals("Sessão inválida", ex.getMessage());
		} try {
			gerenciador.localizaUsuarioPorSessao("20");
		} catch (Exception ex) {
			assertEquals("Sessão inexistente", ex.getMessage());
		}
		gerenciador.reset();
		cadastraUsuarios();
		gerenciador.abrirSessao("login"); gerenciador.abrirSessao("login2");
		assertEquals(gerenciador.usuarios().get(0), gerenciador.localizaUsuarioPorSessao("1"));
		assertEquals(gerenciador.usuarios().get(1), gerenciador.localizaUsuarioPorSessao("2"));
	}

	@Test
	public void testRanking() throws Exception {
		gerenciador.reset();
		cadastraUsuarios();
		try {
			gerenciador.ranking("", gerenciador.usuarios().get(0));
		} catch (Exception ex) {
			assertEquals("Categoria inválida", ex.getMessage());
		} try {
			gerenciador.ranking("blabla", gerenciador.usuarios().get(0));
		} catch (Exception ex) {
			assertEquals("Categoria inexistente", ex.getMessage());
		} simulaEmprestimos();
		assertEquals("mariimello", gerenciador.ranking("amigos", gerenciador.usuarios().get(3)));
		assertEquals("login3; login login2 mariimello marcelinhasilva smithpb", gerenciador.ranking("global", gerenciador.usuarios().get(2)));
	}
	
	private void cadastraUsuarios() throws Exception{
		gerenciador.cadastrarUsuario("nome", "login", "endereco");
		gerenciador.cadastrarUsuario("nomeDois", "login2", "endereco2");
		gerenciador.cadastrarUsuario("nomeTres", "login3", "endereco3");
	}
	
	private void simulaEmprestimos() throws Exception {
		requisitaAmizades();
		Usuario mariana = gerenciador.usuarios().get(0);
		Usuario marcella = gerenciador.usuarios().get(1);
		Usuario ramon = gerenciador.usuarios().get(2);
		
		//cadastrando itens
		mariana.cadastrarItem("Morangos mofados", "livro", "Caio Fernando");
		marcella.cadastrarItem("Morangos mofados2", "livro", "Caio Fernando");
		ramon.cadastrarItem("Harry Potter", "livro", "J.K");
		Item itemMarcella = marcella.gerenteDeItens().getItens().get(0);
		Item itemRamon = ramon.gerenteDeItens().getItens().get(0);
		
		//simulando emprestimos
		mariana.requisitarItem(itemMarcella, 2); marcella.aceitarSolicitacaoDeItem(itemMarcella);
		marcella.requisitarDevolucaoDeItem(itemMarcella); marcella.confirmaDevolucao(itemMarcella);
		mariana.requisitarItem(itemRamon, 2); ramon.aceitarSolicitacaoDeItem(itemRamon);
		mariana.devolverItem(itemRamon);
	}
	
	private void requisitaAmizades() throws Exception {
		gerenciador.cadastrarUsuario("Mariana", "mariimello", "Ipanema");
		gerenciador.cadastrarUsuario("Marcella", "marcelinhasilva", "Jose do Patrocinio");
		gerenciador.cadastrarUsuario("Ramon", "smithpb", "Jose do Patrocinio");
		Usuario mariana = gerenciador.usuarios().get(0);
		Usuario marcella = gerenciador.usuarios().get(1);
		Usuario ramon = gerenciador.usuarios().get(2);
		mariana.requisitarAmizade(marcella); marcella.aprovarAmizade(mariana);
		mariana.requisitarAmizade(ramon); ramon.aprovarAmizade(mariana);
	}
}